(in-package :org.iodb.amazon.ecs)
;;; Class definitions for AWS responses

(defclass price-element (xml:xml-serializer)
  ((amount :accessor amount :initform 0 :initarg :amount)
   (currencycode :accessor currency-code :initform 0 :initarg :currency-code)
   (formattedprice :accessor formatted-price :initform 0 :initarg :formatted-price))
  (:documentation "Parent of all elements that contain price information"))

(defclass general-base-response (xml:xml-serializer)
  ((xmlns :accessor xmlns :initform "" :initarg :xmlns)
   (operationrequest :accessor operation-request :initform nil :initarg :operation-request)
   (items :accessor items :initform nil :initarg :items))
  (:documentation "root of most all operations response"))

(defclass item-search-response (general-base-response)
  ()
  (:documentation "root of item search response"))
(xml:def-element-class-name ItemSearchResponse item-search-response)

(defclass item-lookup-response (general-base-response)
  ()
  (:documentation "root of item lookup responses"))
(xml:def-element-class-name ItemLookupResponse item-lookup-response)

(defclass operation-request (xml:xml-serializer)
  ((httpheaders :accessor httpheaders :initform () :initarg :httpheaders)
   (requestid :accessor requestid :initform "" :initarg requestid)
   (arguments :accessor arguments :initform () :initarg arguments)
   (requestprocessingtime :accessor request-processing-time :initform () :initarg :request-processing-time))
  (:documentation "OperationResponse element in Amazon ECS response"))
(xml:def-element-class-name OperationRequest operation-request)

(defclass http-headers (xml:xml-serializer)
  ((headers :accessor headers :initform () :initarg :headers))
  (:documentation "HTTPHeaders element in Amazon ECS response"))  
(xml:def-element-class-name HTTPHeaders http-headers)

(defclass http-header (xml:xml-serializer)
  ((name :accessor name :initform "" :initarg :name)
   (value :accessor value :initform "" :initarg :value))
  (:documentation "HTTPHeader element in Amazon ECS response"))
(xml:def-element-class-name Header http-header)

(defclass arguments (xml:xml-serializer)
  ((arguments :accessor arguments :initform () :initarg :arguments))
  (:documentation "Arguments element in Amazon ECS response"))  

(defclass argument (xml:xml-serializer)
  ((name :accessor name :initform "" :initarg :name)
   (value :accessor value :initform "" :initarg :value))
  (:documentation "HTTPHeader element in Amazon ECS response"))

(defclass items (xml:xml-serializer)
  ((request :accessor request :initform nil :initarg :request)
   (items :accessor items :initform () :initarg :items)
   (totalresults :accessor total-results :initform 0 :initarg :total-results :type integer)
   (totalpages :accessor total-pages :initform 0 :initarg :total-pages :type integer))
  (:documentation "HTTPHeader element in Amazon ECS response"))

(defclass request (xml:xml-serializer)
  ((isvalid :accessor is-valid :initform nil :initarg :is-valid)
   (errors :accessor errors :initform nil :initarg :errors)
   (itemsearchrequest :accessor item-search-request :initform () :initarg :item-search-request)
   (itemlookuprequest :accessor item-lookup-request :initform () :initarg :item-lookup-request))
  (:documentation "HTTPHeader element in Amazon ECS response"))

(defclass item-search-request (xml:xml-serializer)
  ((keywords :accessor keywords :initform nil :initarg :keywords)
   (merchantid :accessor merchant-id :initform nil :initarg :merchant-id)
   (searchindex :accessor search-index :initform () :initarg :search-index))
  (:documentation "HTTPHeader element in Amazon ECS response"))
(xml:def-element-class-name ItemSearchRequest item-search-request)

(defclass item-lookup-request (xml:xml-serializer)
  ((itemid :accessor item-id :initform nil :initarg :item-id)
   (responsegroups :accessor response-groups :initform () :initarg :response-groups)
   (merchantid :accessor merchant-id :initform () :initarg :merchant-id))
  (:documentation "HTTPHeader element in Amazon ECS response"))
(xml:def-element-class-name ItemLookupRequest item-lookup-request)

(defclass amazon-errors (xml:xml-serializer)
  ((errors :accessor errors :initarg :errors :initform nil)))
(xml:def-element-class-name Errors amazon-errors)


(defclass amazon-error (xml:xml-serializer)
  ((code :accessor code :initarg :code :initform nil)
   (message :accessor message :initarg :message :initform "")))
(xml:def-element-class-name Error amazon-error)


;;; Amazon Item
(defgeneric title (item-like-thing)
  (:documentation "Gives the title of an item-like thing, e.g. ItemAttributes or Item"))
(defgeneric author (item-like-thing)
  (:documentation "Gives the author of an item-like thing, e.g. ItemAttributes or Item"))
(defgeneric isbn (item-like-thing)
  (:documentation "Gives the isbn of an item-like thing, e.g. ItemAttributes or Item"))

(defclass item (xml:xml-serializer)
  ((itemattributes :accessor item-attributes :initform nil :initarg :item-attributes)
   (asin :accessor amazon-asin :initform "" :initarg :amazon-asin)
   (offers :accessor offers :initform () :initarg :offers)
   (alternateversions :accessor alternate-versions :initform nil :initarg :alternate-versions)
   (offersummary :accessor offer-summary :initform () :initarg :offer-summary)
   (detailpageurl :accessor detail-page-url :initform "" :initarg :detail-page-url))
  (:documentation "HTTPHeader element in Amazon ECS response"))

(defmethod title ((item-like-thing item))
  (xml:content (title-element (item-attributes item-like-thing))))
(defmethod author ((item-like-thing item))
  (xml:content (author-element (item-attributes item-like-thing))))
(defmethod isbn ((item-like-thing item))
  (xml:content (isbn-element (item-attributes item-like-thing))))

(defclass offer-summary (xml:xml-serializer)
  ((lowestnewprice :accessor lowest-new-price :initform nil :initarg :lowest-new-price)
   (lowestcollectibleprice :accessor lowest-collectible-price :initform nil :initarg :lowest-collectible-price)
   (lowestusedprice :accessor lowest-used-price :initform nil :initarg :lowest-used-price)
   (totalnew :accessor lowest-used-price :initform nil :initarg :lowest-used-price)
   (totalused :accessor lowest-used-price :initform nil :initarg :lowest-used-price)
   (totalcollectible :accessor lowest-used-price :initform nil :initarg :lowest-used-price)
   (totalrefurbished :accessor lowest-used-price :initform nil :initarg :lowest-used-price))
  (:documentation "Summary of offers for a particular item"))
(xml:def-element-class-name OfferSummary offer-summary)

;(xml:def-element-class-name LowestNewPrice price-element)
;(xml:def-element-class-name LowestUsedPrice price-element)
;(xml:def-element-class-name LowestCollectiblePrice price-element)
;(xml:def-element-class-name LowestRefurbishedPrice price-element)

(defclass lowest-used-price (price-element) nil)
(xml:def-element-class-name LowestUsedPrice lowest-used-price)
(defclass lowest-new-price (price-element) nil)
(xml:def-element-class-name LowestNewPrice lowest-new-price)
(defclass lowest-collectible-price (price-element) nil)
(xml:def-element-class-name LowestCollectiblePrice lowest-collectible-price)
(defclass lowest-reburbished-price (price-element) nil)
(xml:def-element-class-name LowestRefurbishedPrice lowest-reburbished-price)
(defclass price (price-element) nil)
(defclass amount-saved (price-element) nil)
(xml:def-element-class-name AmountSaved amount-saved)

(xml:def-element-class-name Condition xml:xml-serializer)

(defclass offers (xml:xml-serializer)
  ((totaloffers :accessor total-offers :initform nil :initarg :total-offers)
   (totalofferpages :accessor lowest-offer-pages :initform nil :initarg :total-offer-pages)
   (offers :accessor offers :initform () :initarg :offers))
  (:documentation "Summary of offers for a particular item"))

(defclass offer (xml:xml-serializer)
  ((merchant :accessor merchant :initform nil :initarg :merchant)
   (offerattributes :accessor offer-attributes :initform nil :initarg :offer-attributes)
   (seller :accessor seller :initform nil :initarg :seller)
   (offerlisting :accessor offer-listing :initform () :initarg :offer-listing))
  (:documentation "Summary of offers for a particular item"))

(defclass vendor-like-mixin (xml:xml-serializer)
  ((averagefeedbackrating :accessor average-feedback-rating :initform nil :initarg :average-feedback-rating)
   (totalfeedback :accessor total-feedback :initform nil :initarg :total-feedback))
  (:documentation "Mixed into seller and vendor to provide shared slots for the most part"))

(defclass merchant (vendor-like-mixin)
  ((merchantid :accessor merchant-id :initform nil :initarg :merchant-id)
   (glancepage :accessor glance-page :initform nil :initarg :glance-page))
  (:documentation "Summary of offers for a particular item"))

(defclass seller (vendor-like-mixin)
  ((sellerid :accessor seller-id :initform nil :initarg :seller-id))
  (:documentation "Summary of offers for a particular item"))

(defclass offer-attributes (xml:xml-serializer)
  ((condition :accessor offer-condition :initform nil :initarg :condition)
   (conditionnote :accessor condition-note :initform nil :initarg :condition-note)
   (willshipexpedited :accessor will-ship-expedited :initform nil :initarg :will-ship-expedited)
   (willshipinternational :accessor will-ship-international :initform nil :initarg :will-ship-international)
   (subcondition :accessor subcondition :initform nil :initarg :subcondition))
  (:documentation "Summary of offers for a particular item"))
(xml:def-element-class-name OfferAttributes offer-attributes)

(defclass offer-listing (xml:xml-serializer)
  ((offerlistingid :accessor offer-listing-id :initform nil :initarg :offer-listing-id)
   (price :accessor price :initform nil :initarg :price)
   (availability :accessor availability :initform nil :initarg :availability)
   (availabilityattributes :accessor availability-attributes :initform nil :initarg :availability-attributes)
   (amountsaved :accessor amount-saved :initform nil :initarg :amount-saved)
   (percentagesaved :accessor percentage-saved :initform nil :initarg :percentage-saved)
   (exchangeid :accessor exchange-id :initform nil :initarg :exchange-id)
   (quantity :accessor quantity :initform nil :initarg :quantity)
   (iseligibleforsupersavershipping :accessor is-eligible-for-super-saver-shipping :initform nil :initarg :saver-shipping))
  (:documentation "Summary of offers for a particular item"))
(xml:def-element-class-name OfferListing offer-listing)

(defclass availability-attributes (xml:xml-serializer)
  ((availabilitytype :accessor author-element :initform nil :initarg :author-element)
   (minimumhours :accessor title-element :initform "" :initarg :title-element)
   (maximumhours :accessor isbn :initform "" :initarg :isbn))
  (:documentation "HTTPHeader element in Amazon ECS response"))
(xml:def-element-class-name AvailabilityAttributes availability-attributes)

(defclass item-attributes (xml:xml-serializer)
  ((authors :accessor authors-elements :initform nil :initarg :authors-elements)
   (title :accessor title-element :initform "" :initarg :title-element)
   (isbn :accessor isbn :initform "" :initarg :isbn)
   (binding :accessor binding :initform "" :initarg :binding)
   (creators :accessor creators :initform nil :initarg :creators)
   (actors :accessor actors :initform () :initarg :actors)
   (directors :accessor directors :initform nil :initarg :directors)
   (manufacturer :accessor manufacturer :initform "" :initarg :manufacturer)
   (productgroup :accessor product-group :initform "" :initarg :product-group))
  (:documentation "HTTPHeader element in Amazon ECS response"))
(xml:def-element-class-name ItemAttributes item-attributes)

(defclass alternate-version (item-attributes)
  ((asin :accessor amazon-asin :initform nil :initarg :amazon-asin))
  (:documentation "Alternate version of an item."))
(xml:def-element-class-name AlternateVersion alternate-version)

(defclass alternate-versions (xml:xml-serializer)
  ((alternateversions :accessor alternate-version :initform () :initarg :alternate-versions))
  (:documentation "Alternate version of an item."))
(xml:def-element-class-name AlternateVersions alternate-versions)

(defclass creator (xml:xml-serializer)
  ((role :accessor role :initform "" :initarg :role))
  (:documentation ""))